home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / translate / translat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-04  |  4.7 KB  |  193 lines

  1. #include <errno.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6. #include <limits.h>
  7. #include "internal.h"
  8.  
  9. #if defined (unix)
  10.     #include <sys/mman.h>
  11.     #define O_BINARY    0
  12.     static const char *translat_readall(int fd, int size)
  13.     {
  14.         return (const char*)mmap(0,size,PROT_READ,MAP_SHARED,fd,0);
  15.     }
  16.  
  17. #else
  18.     #if defined (UNIX)
  19.         // Just to test the DOS/Windows mode in Unix.
  20.         #include <unistd.h>
  21.         #define O_BINARY    0
  22.     #else
  23.         #include <io.h>
  24.     #endif
  25.     static const char *translat_readall(int fd, int size)
  26.     {
  27.         char *ptm = (char*)malloc(size);
  28.         if (ptm != NULL){
  29.             if (read(fd,ptm,size)!=size){
  30.                 fprintf (stderr,"Can't read messages database\n");
  31.             }
  32.         }else{
  33.             fprintf (stderr,"Can't allocate memory for messages\n");
  34.         }
  35.         close (fd);
  36.         return ptm;
  37.     }
  38.  
  39. #endif
  40. #include "translat.h"
  41.  
  42. static TRANSLATE_SYSTEM_REQ *first = NULL;
  43.  
  44. PUBLIC TRANSLATE_SYSTEM_REQ::TRANSLATE_SYSTEM_REQ(
  45.     const char *_sysname,
  46.     const char **&_global_var,    // Will point to an array
  47.                     // of message (char*)
  48.     int _nb_expected,
  49.     int _version)
  50.     : global_var (_global_var)
  51. {
  52.     nb_expected = _nb_expected;
  53.     version = _version;
  54.     /* #Specification: translate / dictionnary request
  55.         A dictionnary request is done simply by declaring
  56.         a static variable of type TRANSLATE_SYSTEM_REQ.
  57.         We generally defined this variable in the
  58.         source module which is always used within a system.
  59.  
  60.         Sometime, there is no such a module but indeed a few
  61.         module (A library) which are candidate to be included
  62.         in every program which use the librairy.
  63.  
  64.         It is possible to declare several static
  65.         TRANSLATE_SYSTEM_REQ, one in every module we need. These
  66.         request should use obviously the same name and
  67.         the same global variable.
  68.  
  69.         Special macros are automagically defined by
  70.         msgscan to insure consistency.
  71.     */
  72.     TRANSLATE_SYSTEM_REQ *pt = first;
  73.     while (pt != NULL){
  74.         if (strcmp(pt->sysname,_sysname)==0)break;
  75.         pt = pt->next;
  76.     }
  77.     if (pt == NULL){
  78.         next = first;
  79.         first = this;
  80.         sysname = _sysname;
  81.     }
  82. }
  83. static char *pterr = NULL;
  84. /*
  85.     Print an error message and increment the err counter
  86. */
  87. static void translat_err (const char *msg, ...)
  88. {
  89.     va_list list;
  90.     va_start (list,msg);
  91.     pterr += vsprintf (pterr,msg,list);
  92.     va_end (list);
  93. }
  94.  
  95.  
  96.  
  97. static void translat_alloc (
  98.     BDICT_SYSTEM *tbsys,
  99.     int nbsys,
  100.     const char *ptm)
  101. {
  102.     TRANSLATE_SYSTEM_REQ *req = first;
  103.     while (req != NULL){
  104.         long offset = sizeof(BDICT_HEADER)+nbsys * sizeof(BDICT_SYSTEM);
  105.         BDICT_SYSTEM *ptsys = tbsys;
  106.         int i;
  107.         for (i=0; i<nbsys; i++, ptsys++){
  108.             int nbmsg = ptsys->nbmsg;
  109.             if (strcmp(req->sysname,ptsys->name)==0){
  110.                 if (req->version > ptsys->version){
  111.                     translat_err ("sub-dictionnary %s: Invalid version %d < %d\n"
  112.                         ,req->sysname,ptsys->version,req->version);
  113.                 }else if (req->nb_expected > ptsys->nbmsg){
  114.                     translat_err ("sub-dictionnary %s: Not enough messages %d < %d\n"
  115.                         ,req->sysname,ptsys->nbmsg,req->nb_expected);
  116.                 }else{
  117.                     req->global_var = (const char**)malloc(nbmsg*sizeof(char*));
  118.                     const char **ptvar = req->global_var;
  119.                     long *ptoff = (long*)(ptm + offset);
  120.                     for (int m=0; m<nbmsg; m++, ptvar++, ptoff++){
  121.                         *ptvar = ptm + *ptoff;
  122.                     }
  123.                 }
  124.                 break;
  125.             }else{
  126.                 offset += nbmsg * sizeof(long);
  127.             }
  128.         }
  129.         if (i==nbsys){
  130.             translat_err ("Unknown dictionnary %s\n",req->sysname);
  131.         }
  132.         req = req->next;
  133.     }
  134. }
  135.  
  136.  
  137. /*
  138.     Charge le dictionnaire de messages.
  139.     Retourne -1 s'il y a des erreurs.
  140. */
  141. int translat_load (
  142.     const char *basepath,    // Directory holding dictionnaries
  143.     const char *basename,    // base name of the dictionnary
  144.                 // the language selection will supply
  145.                 // the extension.
  146.     char *errmsg)        // Contiendra le message d'erreur
  147. {
  148.     errmsg[0] = '\0';
  149.     pterr = errmsg;
  150.     char path[128];
  151.     sprintf (path,"%s/%s",basepath,basename);
  152.     int fd  = open (path,O_BINARY|O_RDONLY);
  153.     if (fd == -1){
  154.         translat_err ("Can't load dictionnary file %s (%s)\n"
  155.             ,path,strerror (errno));
  156.     }else{
  157.         struct stat st;
  158.         stat (path,&st);
  159.         const char *ptm = translat_readall (fd,st.st_size);
  160.         if (ptm != NULL){
  161.             BDICT_HEADER *hd = (BDICT_HEADER*)ptm;
  162.             if (hd->magic != BDICT_MAGIC){
  163.                 translat_err ("Invalid dictionnary magic word\n");
  164.             }else if (hd->version != BDICT_VERSION){
  165.                 translat_err ("Invalid dictionnary version\n");
  166.             }else{
  167.                 BDICT_SYSTEM *tbsys
  168.                     = (BDICT_SYSTEM*)(ptm+sizeof(BDICT_HEADER));
  169.                 translat_alloc (tbsys,hd->nbsys,ptm);
  170.             }
  171.         }
  172.     }
  173.     return pterr > errmsg ? -1 : 0;
  174. }
  175.  
  176. /*
  177.     Charge le dictionnaire de messages.
  178.     Termine s'il y a des erreurs.
  179. */
  180. void translat_load (
  181.     const char *basepath,    // Directory holding dictionnaries
  182.     const char *basename)    // base name of the dictionnary
  183.                 // the language selection will supply
  184.                 // the extension.
  185. {
  186.     char errmsg[2000];
  187.     if (translat_load (basepath,basename,errmsg)==-1){
  188.         fprintf (stderr,"%s",errmsg);
  189.         exit (-1);
  190.     }
  191. }
  192.  
  193.